package server.net.handler;

import game.GameInstance;
import game.Player;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
import server.GameServer;
import server.net.Client;
import shared.net.protocol.PacketCreator;
import shared.util.PacketIO;

/**
 * 
 * This class handles requests between clients to play against each other.
 * 
 * @author Vincent Tsuei
 * @version 2012-11-28
 */
public class GameRequestHandler implements ServerPacketHandler {
    

    @Override
    public int processPacket(Client client, ByteBuffer packet) {
        if (!client.isLoggedIn()) {
            client.getConnection().queuePacketSend(PacketCreator.LOBBY.PLAY.getNewGameFailureResponse("You are not logged in!"));
            return -1;
        }
        
        String other = PacketIO.readString(packet);
        GameServer server = client.getGameServer();
        
        if (client.getPlayer().getName().equals(other)) {
            client.getConnection().queuePacketSend(PacketCreator.LOBBY.PLAY.getNewGameFailureResponse("You cannot invite yourself to a game."));
            return -1; //Inviting ourselves.
        }
        
        if (!server.getPlayerRegistry().containsPlayer(other)) {
            client.getConnection().queuePacketSend(PacketCreator.LOBBY.PLAY.getNewGameFailureResponse("Player " + other + " is not logged in to the server."));
            return -1; //Person not logged in.
        }
        
        Player P = client.getPlayer();
        Player otherP = server.getPlayerRegistry().getPlayer(other);
        if (otherP != null) {
            
            // Both players need to be in the lobby.
            if (!P.isInLobby()) {
                //Hack - or bug.
                client.getConnection().queuePacketSend(PacketCreator.LOBBY.PLAY.getNewGameFailureResponse("You are not in the lobby!"));
                return -1;
            }
            if (!otherP.isInLobby()) {
                client.getConnection().queuePacketSend(PacketCreator.LOBBY.PLAY.getNewGameFailureResponse("That person is already playing or observing a game. Try again later."));
                return -1;
            }
            
            // Check invite permissions first.
            if (!P.canInvite()) {
                //For our current implementation, THIS IS A BUG.
                client.getConnection().queuePacketSend(PacketCreator.LOBBY.PLAY.getNewGameFailureResponse("Your invites are disabled right now."));
                return -1;
            }
            if (!otherP.canInvite()) {
                //This happens when we send an invite at the instant someone disconnects.
                client.getConnection().queuePacketSend(PacketCreator.LOBBY.PLAY.getNewGameFailureResponse("That person cannot receive invites right now. (They may be logging out)"));
                return -1;
            }
            
            // Now check if there are already invites in progress.
            if (P.hasInvited(otherP) && otherP.hasBeenInvitedBy(P)) {
                client.getConnection().queuePacketSend(PacketCreator.LOBBY.PLAY.getNewGameFailureResponse("You've already invited that person to a game. Please wait for a reply ..."));
                return -1;
            } else if (P.hasBeenInvitedBy(otherP) && otherP.hasInvited(P)) {
                System.out.println(P.getName() + " accepted invitation from " + otherP.getName());
                
                //Accept the invitation
                boolean acceptInvitation = P.acceptInvite(otherP);
                if (!acceptInvitation) {
                    client.getConnection().queuePacketSend(PacketCreator.LOBBY.PLAY.getNewGameFailureResponse("That person may have logged off or started playing/observing another game. Try again later."));
                    return -1;
                }
                return 0;
            } else if (!P.hasInvited(otherP) && !otherP.hasInvited(P) && !P.hasBeenInvitedBy(otherP) && !otherP.hasBeenInvitedBy(P)) {
                System.out.println("Invitation from " + P.getName() + " to " + otherP.getName());
                
                //Send an invitation
                boolean success = P.invite(otherP);
                if (success) {
                    client.getConnection().queuePacketSend(PacketCreator.LOBBY.PLAY.getGameInviteSuccess());
                    return 0;
                } else {
                    client.getConnection().queuePacketSend(PacketCreator.LOBBY.PLAY.getNewGameFailureResponse("Something went wrong with the invite. Try again later."));
                    return -1;
                }
            } else {
                //THIS IS A SERIOUS ERROR. MUST BE A SYNC ISSUE WITH INVITES.
                Logger.getLogger(GameRequestHandler.class.getName()).log(Level.SEVERE, "!!! PLAYER INVITE STATES MISMATCH !!!");
                return -1;
            }
        } else {
            //Logged out while we were retrieving them.
            client.getConnection().queuePacketSend(PacketCreator.LOBBY.PLAY.getNewGameFailureResponse("Player " + other + " is not logged in to the server anymore."));
            return -1;
        }
    }
    
}
